home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok46.lha / M2SDS / CONTOOLS.IMP < prev    next >
Text File  |  1993-08-15  |  32KB  |  1,041 lines

  1.  
  2. IMPLEMENTATION MODULE ConTools;
  3.   FROM SYSTEM IMPORT SWI, RegAX, RegCX, STRING;
  4.   FROM ASCII IMPORT space, esc, bs, bel;
  5.   IMPORT Terminal;
  6.   FROM String IMPORT StrToArray, ArrayToStr;
  7.   IMPORT String;
  8.   FROM Geometry IMPORT Point, Rectangle;
  9.   FROM Screen IMPORT Fore, Back, SetCursor, Scroll, Colors;
  10.   IMPORT Screen;
  11.   CONST
  12.     sp = space;
  13.     ControlC = 3C;
  14.     cr = 36C;
  15.   VAR
  16.     Cursor : Point;
  17.     aBereich : TBereich;
  18.   (*---------------------------------------------------------------------
  19.     * Proceduren zur Behandlung von Strings als ARRAY OF CHAR,
  20.     * hier implementiert da nicht zur Verfgung gestellt.
  21.     ---------------------------------------------------------------------
  22.     *)
  23.   PROCEDURE Length(Satz : ARRAY OF CHAR): CARDINAL;
  24.     VAR
  25.       i : CARDINAL;
  26.     BEGIN
  27.       i := 0;
  28.       WHILE (i<HIGH(Satz)) AND (Satz[i]#0C) DO
  29.         INC(i);
  30.       END;
  31.       RETURN i;
  32.     END Length;
  33.   PROCEDURE Copy(VAR S1 : ARRAY OF CHAR; S2 : ARRAY OF CHAR);
  34.     VAR
  35.       i : CARDINAL;
  36.     BEGIN
  37.       i := 0;
  38.       WHILE (i<HIGH(S1)) AND (i<HIGH(S2)) AND (S2[i]#0C) DO
  39.         S1[i] := S2[i];
  40.         INC(i);
  41.       END;
  42.       S1[i] := 0C;
  43.     END Copy;
  44.   PROCEDURE Delete(VAR S : ARRAY OF CHAR; Pos, Count : CARDINAL);
  45.     VAR
  46.       str : STRING[255];
  47.     BEGIN
  48.       ArrayToStr(S, str);
  49.       String.Delete(str, Pos+1, Count);
  50.       StrToArray(str, S);
  51.     END Delete;
  52.   (*--------------------------------------------------------------------
  53.     * Ausgaberoutinen, aufbauend auf Write.
  54.     --------------------------------------------------------------------
  55.     *)
  56.   PROCEDURE Write(Zeichen : CHAR);
  57.     (*
  58.       * Write:
  59.       *  Ausgabe eines einzelnen Zeichens, falls ausgebbar.
  60.       *  Der aktuelle Bereich wird beachtet.
  61.     *)
  62.     BEGIN
  63.       IF Zeichen>=sp THEN
  64.         IF Cursor.x<aBereich.B.left THEN
  65.           Cursor.x := aBereich.B.left;
  66.         ELSIF Cursor.x>aBereich.B.right THEN
  67.           Cursor.x := aBereich.B.right;
  68.         END;
  69.         IF Cursor.y<aBereich.B.top THEN
  70.           Cursor.y := aBereich.B.top;
  71.         ELSIF Cursor.y>aBereich.B.bottom THEN
  72.           Cursor.y := aBereich.B.bottom;
  73.         END;
  74.         IF Cursor.x<aBereich.B.right THEN
  75.           SetCursor(Cursor);
  76.           Screen.Write(Zeichen);
  77.           INC(Cursor.x);
  78.         ELSIF Cursor.y<aBereich.B.bottom-1 THEN
  79.           Cursor.x := aBereich.B.left;
  80.           INC(Cursor.y);
  81.           SetCursor(Cursor);
  82.           Screen.Write(Zeichen);
  83.         ELSE
  84.           Cursor.x := aBereich.B.left;
  85.           Cursor.y := aBereich.B.bottom-1;
  86.           Scroll(aBereich.B, 1);
  87.           SetCursor(Cursor);
  88.           Screen.Write(Zeichen);
  89.         END;
  90.       END;
  91.     END Write;
  92.   PROCEDURE WriteLn();
  93.     (*
  94.       * WriteLn:
  95.       *  Ausgabe in neue Zeile, bei der letzten Zeile des Bereiches wird 
  96.       *  dieser gescrollt.
  97.     *)
  98.     BEGIN
  99.       Cursor.x := aBereich.B.left;
  100.       IF Cursor.y<aBereich.B.bottom-1 THEN
  101.         INC(Cursor.y);
  102.         SetCursor(Cursor);
  103.       ELSE
  104.         Cursor.y := aBereich.B.bottom-1;
  105.         Scroll(aBereich.B, 1);
  106.         SetCursor(Cursor);
  107.       END;
  108.     END WriteLn;
  109.   PROCEDURE WriteString(Satz : ARRAY OF CHAR);
  110.     (*
  111.       * WriteString:
  112.       *  Ausgabe des Satzes mittels Write. Das Satzende muá mit dem
  113.       *  Nullzeichen terminiert sein, falls weniger als HIGH (Satz) Zeichen
  114.       *  auszugeben sind.
  115.     *)
  116.     VAR
  117.       i : CARDINAL;
  118.     BEGIN
  119.       i := 0;
  120.       WHILE (i<=HIGH(Satz)) AND (Satz[i]#0C) DO
  121.         Write(Satz[i]);
  122.         INC(i);
  123.       END;
  124.     END WriteString;
  125.   PROCEDURE CardToArray(VAR Satz : ARRAY OF CHAR; Zahl : CARDINAL; 
  126.       n : INTEGER);
  127.     (*
  128.       * CardToArray:
  129.       *  Hilfsprocedur, insbesondere fr WriteCard.
  130.       *  Die Zahl wird in den Satz bertragen, formatiert auf n Zeichen,
  131.       *  Fr positive n erfolgt die Formatierung rechtsbndig, fr negative 
  132.       *  linksbndig.
  133.     *)
  134.     VAR
  135.       i, z, h : CARDINAL;
  136.       S : ARRAY [0..20] OF CHAR;
  137.     BEGIN
  138.       (*                                                  L„nge gltig? *)
  139.       IF (n>0) AND (n>INTEGER(HIGH(Satz))) THEN
  140.         n := INTEGER(HIGH(Satz));
  141.       ELSIF (n<0) AND (-n>INTEGER(HIGH(Satz))) THEN
  142.         n := -INTEGER(HIGH(Satz));
  143.       END;
  144.       IF n>20 THEN
  145.         n := 20;
  146.       ELSIF n<-20 THEN
  147.         n := -20;
  148.       END;
  149.       i := 0;
  150.       (*                                          n”tige Ziffern z„hlen *)
  151.       IF Zahl=0 THEN
  152.         (*                                              Sonderfall Null *)
  153.         z := 1;
  154.       ELSE
  155.         (*              Ziffern in umgekehrter Reihenfolge in S sichern *)
  156.         h := Zahl;
  157.         z := 0;
  158.         WHILE h>0 DO
  159.           S[z] := CHR((h MOD 10)+ORD("0"));
  160.           h := h DIV 10;
  161.           INC(z);
  162.         END;
  163.       END;
  164.       (*                                            rechtsbndig fllen *)
  165.       WHILE INTEGER(i+z) < n DO
  166.         Satz[i] := " ";
  167.         INC(i);
  168.       END;
  169.       IF Zahl=0 THEN
  170.         (*                                              Sonderfall Null *)
  171.         Satz[i] := "0";
  172.         INC(i);
  173.       ELSE
  174.         (*                         in S gespeicherte Ziffern umkopieren *)
  175.         WHILE z>0 DO
  176.           DEC(z);
  177.           Satz[i] := S[z];
  178.           INC(i);
  179.         END;
  180.       END;
  181.       (*                                              linksbnig fllen *)
  182.       WHILE INTEGER(i) < n DO
  183.         Satz[i] := " ";
  184.         INC(i);
  185.       END;
  186.       (*                                    Terminationszeichen anfgen *)
  187.       IF i<HIGH(Satz) THEN
  188.         Satz[i] := 0C;
  189.       END;
  190.     END CardToArray;
  191.   PROCEDURE WriteCard(Zahl : CARDINAL; n : INTEGER);
  192.     (*
  193.       * WriteCard:
  194.       *  Die Zahl wird mit CardToArray in den Satz konvertiert und 
  195.       *  ausgeben.
  196.     *)
  197.     VAR
  198.       i : INTEGER;
  199.       satz : ARRAY [0..10] OF CHAR;
  200.     BEGIN
  201.       CardToArray(satz, Zahl, n);
  202.       WriteString(satz);
  203.     END WriteCard;
  204.   PROCEDURE IntToArray(VAR Satz : ARRAY OF CHAR; Zahl : LONGINT; n : 
  205.       INTEGER);
  206.     (*
  207.       * IntToArray:
  208.       *  Hilfsprocedure, siehe auch CardToArray.
  209.       *  Die Zahl wir formatiert in den Satz gespeichert.
  210.      *)
  211.     VAR
  212.       i, z, Negativ : CARDINAL;
  213.       h : LONGINT;
  214.       S : ARRAY [0..20] OF CHAR;
  215.     BEGIN
  216.       IF (n>0) AND (n>INTEGER(HIGH(Satz))) THEN
  217.         n := INTEGER(HIGH(Satz));
  218.       ELSIF (n<0) AND (-n>INTEGER(HIGH(Satz))) THEN
  219.         n := -INTEGER(HIGH(Satz));
  220.       END;
  221.       IF n>20 THEN
  222.         n := 20;
  223.       ELSIF n<-20 THEN
  224.         n := -20;
  225.       END;
  226.       (*                                        Negativ ist Sonderfall *)
  227.       IF Zahl<LONGINT(0) THEN
  228.         Zahl := -Zahl;
  229.         Negativ := 1;
  230.       ELSE
  231.         Negativ := 0;
  232.       END;
  233.       IF Zahl=LONGINT(0) THEN
  234.         z := 1;
  235.       ELSE
  236.         h := Zahl;
  237.         z := 0;
  238.         WHILE h>LONGINT(0) DO
  239.           S[z] := CHR(CARDINAL(h MOD LONGINT(10))+ORD("0"));
  240.           h := h DIV LONGINT(10);
  241.           INC(z);
  242.         END;
  243.       END;
  244.       i := 0;
  245.       WHILE INTEGER(i+z+Negativ) < n DO
  246.         Satz[i] := " ";
  247.         INC(i);
  248.       END;
  249.       IF Zahl=LONGINT(0) THEN
  250.         Satz[i] := "0";
  251.         INC(i);
  252.       ELSE
  253.         (*                       Falls Negativ Minuszeichen vorsetzten *)
  254.         IF Negativ=1 THEN
  255.           Satz[i] := "-";
  256.           INC(i);
  257.         END;
  258.         WHILE z>0 DO
  259.           DEC(z);
  260.           Satz[i] := S[z];
  261.           INC(i);
  262.         END;
  263.       END;
  264.       WHILE n < -INTEGER (i) DO
  265.         Satz[i] := " ";
  266.         INC(i);
  267.       END;
  268.       IF i<HIGH(Satz) THEN
  269.         Satz[i] := 0C;
  270.       ELSE
  271.         Satz[HIGH(Satz)] := 0C;
  272.       END;
  273.     END IntToArray;
  274.   PROCEDURE ArrayToInt(VAR Zahl : LONGINT; Satz : ARRAY OF CHAR; 
  275.     VAR Fehler : BOOLEAN);
  276.     (*
  277.       * ArrayToInt:
  278.       *  Konvertierung eines Satzes in eine Zahl,
  279.       *  der Satz darf als erstes Zeichen nur ein Minuszeichen oder
  280.       *  Ziffern enthalten, weiter sind nur Ziffern erlaubt.
  281.       *  Der Parameter Fehler gibt den Erfolg der Umwandlung wieder.
  282.     *)
  283.     VAR
  284.       i : CARDINAL;
  285.       Negativ : BOOLEAN;
  286.     BEGIN
  287.       (*                                               Initialisierung *)
  288.       Fehler := FALSE;
  289.       Zahl := LONGINT(0);
  290.       i := 0;
  291.       (*                                      Minuszeichen herausl”sen *)
  292.       Negativ := (Satz[i]="-");
  293.       IF Negativ THEN
  294.         INC(i);
  295.       END;
  296.       (*                                     Ziffernweise konvertieren *)
  297.       WHILE (i<HIGH(Satz)) AND (Satz[i]#0C) DO
  298.         IF ("0"<=Satz[i]) AND (Satz[i]<="9") THEN
  299.           Zahl := Zahl*LONGINT(10)+LONGINT(ORD(Satz[i])-ORD("0"));
  300.           INC(i);
  301.         ELSE
  302.           Fehler := TRUE;
  303.           RETURN;
  304.         END;
  305.       END;
  306.       (*                                       Sonderfall Zahl Negativ *)
  307.       IF Negativ THEN
  308.         Zahl := -Zahl;
  309.       END;
  310.     END ArrayToInt;
  311.   PROCEDURE WriteInt(Zahl : LONGINT; n : INTEGER);
  312.     (*
  313.       * WriteInt:
  314.       *  Ausgabe einer Zahl, siehe auch WriteCard.
  315.     *)
  316.     VAR
  317.       i : INTEGER;
  318.       satz : ARRAY [0..20] OF CHAR;
  319.     BEGIN
  320.       IntToArray(satz, Zahl, n);
  321.       WriteString(satz);
  322.     END WriteInt;
  323.   (*
  324.     ---------------------------------------------------------------------
  325.     *)
  326.   PROCEDURE ZeichenIstErlaubt(Zeichen : CHAR; erlaubteZeichen : 
  327.       TZeichenMenge; VAR Status : TStatus): BOOLEAN;
  328.     (*
  329.       * ZeichenIstErlaubt:
  330.       *  interne Hilfsfunktion,
  331.       *  stellt fest, welches Zeichen welchen Status ergibt.
  332.       *  Resultat: "Zeichen IN erlaubteZeichen"
  333.     *)
  334.     BEGIN
  335.       IF SonderEingabe THEN
  336.         CASE Zeichen OF
  337.         | func1..func10 :
  338.           Status := VAL(TStatus,(ORD(Zeichen)-ORD(func1)+ORD(
  339.               Funktion1)));
  340.         | sfunc1..sfunc10 :
  341.           Status := VAL(TStatus,(ORD(Zeichen)-ORD(sfunc1)+ORD(
  342.               sFunktion1)));
  343.         | help :
  344.           Status := Hilfe;
  345.         | up :
  346.           Status := Oben;
  347.         | down :
  348.           Status := Unten;
  349.         | sup :
  350.           Status := SeiteOben;
  351.         | sdown :
  352.           Status := SeiteUnten;
  353.         | btab :
  354.           Status := Links;
  355.         | ins :
  356.           Status := Funktion9;
  357.         | pos1 :
  358.           Status := sFunktion10;
  359.         | end :
  360.           Status := Funktion10;
  361.         | sleft, sright, del, left, right :
  362.           RETURN TRUE;
  363.         ELSE
  364.           RETURN FALSE;
  365.         END;
  366.       ELSE
  367.         CASE Zeichen OF
  368.         | esc :
  369.           Status := Zurueck;
  370.         | tab :
  371.           Status := Rechts;
  372.         | cr :
  373.           Status := Ende;
  374.         | bs, sp :
  375.           RETURN TRUE;
  376.         ELSE
  377.           IF (CAP(Zeichen)="J") OR (CAP(Zeichen)="N") THEN
  378.             RETURN (JaNein IN erlaubteZeichen) OR (Buchstaben IN 
  379.                 erlaubteZeichen) OR (alleZeichen IN erlaubteZeichen);
  380.           ELSIF (("A"<=Zeichen) AND (Zeichen<="Z") OR ("a"
  381.               <=Zeichen) AND (Zeichen<="z")) THEN
  382.             RETURN (Buchstaben IN erlaubteZeichen) OR (alleZeichen IN 
  383.                 erlaubteZeichen);
  384.           ELSIF ("0"<=Zeichen) AND (Zeichen<="9") THEN
  385.             RETURN (Ziffern IN erlaubteZeichen) OR (eZiffern IN 
  386.                 erlaubteZeichen) OR (alleZeichen IN erlaubteZeichen);
  387.           ELSIF (Zeichen="+") OR (Zeichen="-") OR (Zeichen=".") THEN
  388.             RETURN (eZiffern IN erlaubteZeichen) OR (alleZeichen IN 
  389.                 erlaubteZeichen);
  390.           ELSE
  391.             RETURN alleZeichen IN erlaubteZeichen;
  392.           END;
  393.         END;
  394.       END;
  395.       IF ((Status>=Funktion1) AND (Funktion IN erlaubteZeichen)) 
  396.           OR ((Status<Funktion1) AND (VAL(TZeichen,ORD(Status)-ORD(
  397.           Ende)) IN erlaubteZeichen)) THEN
  398.         RETURN TRUE;
  399.       ELSE
  400.         Status := Normal;
  401.         RETURN FALSE;
  402.       END;
  403.     END ZeichenIstErlaubt;
  404.   (*
  405.     ---------------------------------------------------------------------
  406.     *)
  407.   PROCEDURE TasteGedrueckt(): BOOLEAN;
  408.     (*
  409.       * TasteGedrueckt:
  410.       *  Resultat: BOOLEAN, ob noch Zeichen im Tastaturbuffer sind,
  411.       *  intern realisiert ber Terminal, BIOS Funktion.
  412.     *)
  413.     BEGIN
  414.       RETURN Terminal.BusyRead();
  415.     END TasteGedrueckt;
  416.   PROCEDURE Read(VAR Zeichen : CHAR);
  417.     (*
  418.       * Read:
  419.       *  Einlesen eines Zeichens ohne Echo, bei einer Sondereingabe wird
  420.       *  die Variable gesetzt.
  421.       *  intern ber Terminal, BIOS Funktion.
  422.     *)
  423.     BEGIN
  424.       Terminal.Read(Zeichen);
  425.       SonderEingabe := (Zeichen=0C);
  426.       IF SonderEingabe THEN
  427.         Terminal.Read(Zeichen);
  428.       END;
  429.     END Read;
  430.   PROCEDURE ReadString(X, Y, Laenge : CARDINAL; erlaubteZeichen : 
  431.       TZeichenMenge; VAR Satz : ARRAY OF CHAR);
  432.     (*
  433.       * ReadString:
  434.       *  Eingabe eines Satzes, siehe auch Definitionsmodul.
  435.     *)
  436.     VAR
  437.       i, Pos : CARDINAL;
  438.       Zeichen : CHAR;
  439.     BEGIN
  440.       (*                    Return erlaubt, sonst nicht terminierend. *)
  441.       INCL(erlaubteZeichen, Return);
  442.       Pos := 0;
  443.       (*          Satz auf Laenge bringen, ggf mit Leerzeichen fllen *)
  444.       i := 0;
  445.       WHILE (Satz[i]#0C) AND (i<HIGH(Satz)) DO
  446.         INC(i);
  447.       END;
  448.       IF i>Laenge THEN
  449.         Satz[Laenge] := 0C;
  450.       ELSE
  451.         WHILE i<Laenge DO
  452.           Satz[i] := sp;
  453.           INC(i);
  454.         END;
  455.         Satz[Laenge] := 0C;
  456.       END;
  457.       (*                                           Ausgabe des Satzes *)
  458.       InverseAusgabe();
  459.       SetzePosition(X, Y);
  460.       WriteString(Satz);
  461.       Status := Normal;
  462.       REPEAT
  463.         (*                                Cursor auf Position bringen *)
  464.         SetzePosition(X+Pos, Y);
  465.         CursorAn();
  466.         (*                                 erlaubtes Zeichen einlesen *)
  467.         REPEAT
  468.           Read(Zeichen);
  469.         UNTIL ZeichenIstErlaubt(Zeichen,erlaubteZeichen+TZeichenMenge{
  470.             Funktion},Status);
  471.         CursorAus();
  472.         IF SonderEingabe THEN
  473.           CASE Zeichen OF
  474.           | left :
  475.                                                 (* Zeichen links *)
  476.             IF Pos>0 THEN
  477.               DEC(Pos);
  478.             END;
  479.           | right :
  480.                                                 (* Zeichen rechts *)
  481.             IF Pos<Laenge-1 THEN
  482.               INC(Pos);
  483.             END;
  484.           | del :
  485.                                                 (* Zeichen rechts l”schen *)
  486.             i := Pos+1;
  487.             WHILE (i<Laenge-1) DO
  488.               Satz[i-1] := Satz[i];
  489.               INC(i);
  490.             END;
  491.             Satz[Laenge-1] := sp;
  492.             SetzePosition(X, Y);
  493.             WriteString(Satz);
  494.           | end, func10 :
  495.                                                 (* Ende *)
  496.             Status := Normal;
  497.             Pos := Laenge-1;
  498.             WHILE (Pos>0) AND (Satz[Pos]=sp) DO
  499.               DEC(Pos);
  500.             END;
  501.             IF Pos<Laenge-1 THEN
  502.               INC(Pos);
  503.             END;
  504.           | pos1, sfunc10 :
  505.                                                 (* Anfang *)
  506.             Status := Normal;
  507.             Pos := 0;
  508.           | ins, func9 :
  509.                                                 (* Leerzeichen einfgen *)
  510.             Status := Normal;
  511.             FOR i := Laenge-1 TO Pos+1 BY -1 DO
  512.               Satz[i] := Satz[i-1];
  513.             END;
  514.             Satz[Pos] := sp;
  515.             SetzePosition(X, Y);
  516.             WriteString(Satz);
  517.           | sfunc9 :
  518.                                                 (* Alles l”schen *)
  519.             Status := Normal;
  520.             Pos := Laenge;
  521.             Satz[Laenge] := 0C;
  522.             WHILE Pos>0 DO
  523.               DEC(Pos);
  524.               Satz[Pos] := sp;
  525.             END;
  526.             SetzePosition(X, Y);
  527.             WriteString(Satz);
  528.           | func8 :
  529.                                                 (* L”sche bis Ende *)
  530.             Status := Normal;
  531.             i := Pos;
  532.             WHILE i<Laenge DO
  533.               Satz[i] := sp;
  534.               INC(i);
  535.             END;
  536.             SetzePosition(X, Y);
  537.             WriteString(Satz);
  538.           | sfunc8 :
  539.                                                 (* L”sche bis Anfang *)
  540.             Status := Normal;
  541.             IF Pos>0 THEN
  542.               Delete(Satz, 0, Pos);
  543.               i := Length(Satz);
  544.               WHILE i<Laenge DO
  545.                 Satz[i] := sp;
  546.                 INC(i);
  547.               END;
  548.               Satz[Laenge] := 0C;
  549.               SetzePosition(X, Y);
  550.               WriteString(Satz);
  551.               Pos := 0;
  552.             END;
  553.           | sleft :
  554.                                                 (* Wort links *)
  555.             WHILE (Pos>0) AND ((Satz[Pos]<"A") OR (("Z"
  556.                 <Satz[Pos]) AND (Satz[Pos]<"a")) OR (("z"
  557.                 <Satz[Pos]) AND (Satz[Pos]<200C)) OR (245C<Satz[Pos])) DO
  558.               DEC(Pos);
  559.             END;
  560.             WHILE (Pos>0) AND ((("A"<=Satz[Pos]) AND (Satz[Pos]<="Z"
  561.                 )) OR (("a"<=Satz[Pos]) AND (Satz[Pos]<="z"
  562.                 )) OR ((200C<=Satz[Pos]) AND (Satz[Pos]<=245C))) DO
  563.               DEC(Pos);
  564.             END;
  565.           | sright :
  566.                                                 (* Wort rechts *)
  567.             WHILE (Pos<Laenge-1) AND ((Satz[Pos]<"A") OR (("Z"
  568.                 <Satz[Pos]) AND (Satz[Pos]<"a")) OR (("z"
  569.                 <Satz[Pos]) AND (Satz[Pos]<200C)) OR (245C<Satz[Pos])) DO
  570.               INC(Pos);
  571.             END;
  572.             WHILE (Pos<Laenge-1) AND ((("A"
  573.                 <=Satz[Pos]) AND (Satz[Pos]<="Z")) OR (("a"
  574.                 <=Satz[Pos]) AND (Satz[Pos]<="z"
  575.                 )) OR ((200C<=Satz[Pos]) AND (Satz[Pos]<=245C))) DO
  576.               INC(Pos);
  577.             END;
  578.           ELSE
  579.             IF (NOT (Funktion IN erlaubteZeichen)) AND (Status>=
  580.                 Funktion1) THEN
  581.               Status := Normal;
  582.             END;
  583.           END;
  584.         ELSE
  585.        (* NOT SonderEingabe *)
  586.           CASE Zeichen OF
  587.           | cr, esc :
  588.                                                 (* Leer; Status schon gesetzt *)
  589.           | bs :
  590.                                                 (* Zeichen links l”schen *)
  591.             IF Pos>0 THEN
  592.               DEC(Pos);
  593.               i := Pos;
  594.               WHILE (i<Laenge-1) DO
  595.                 Satz[i] := Satz[i+1];
  596.                 INC(i);
  597.               END;
  598.               Satz[Laenge-1] := sp;
  599.               SetzePosition(X, Y);
  600.               WriteString(Satz);
  601.             END;
  602.           ELSE
  603.                                                 (* Normale Eingabe *)
  604.             Satz[Pos] := Zeichen;
  605.             SetzePosition(X+Pos, Y);
  606.             Write(Zeichen);
  607.             IF Pos<Laenge-1 THEN
  608.               INC(Pos);
  609.             END;
  610.           END;
  611.         END;
  612.         (*                       Ende der Eingabe falls Status gesetzt *)
  613.       UNTIL Status#Normal;
  614.       (*                       Satz wieder in normaler Farbe ausgeben. *)
  615.       NormaleAusgabe();
  616.       SetzePosition(X, Y);
  617.       WriteString(Satz);
  618.       (*                           abschlieáende Leerzeichen entfernen *)
  619.       i := Laenge;
  620.       WHILE (i>0) AND (Satz[i-1]=sp) DO
  621.         DEC(i);
  622.         Satz[i] := 0C;
  623.       END;
  624.     END ReadString;
  625.   PROCEDURE ReadLongInt(X, Y, Laenge : CARDINAL; erlaubteZeichen : 
  626.       TZeichenMenge; VAR Zahl : LONGINT);
  627.     (*
  628.       * ReadLongInt:
  629.       *  Eingabe einer korrekten Zahl mit ReadString.
  630.     *)
  631.     VAR
  632.       Fehler : BOOLEAN;
  633.       i : CARDINAL;
  634.       Satz : ARRAY [0..15] OF CHAR;
  635.     BEGIN
  636.       erlaubteZeichen := erlaubteZeichen-TZeichenMenge{alleZeichen,
  637.           Buchstaben,JaNein}+TZeichenMenge{eZiffern};
  638.       IF Laenge>15 THEN
  639.         Laenge := 15;
  640.       END;
  641.       IntToArray(Satz, Zahl, -INTEGER(Laenge));
  642.       REPEAT
  643.         ReadString(X, Y, Laenge, erlaubteZeichen, Satz);
  644.         ArrayToInt(Zahl, Satz, Fehler);
  645.         IF Fehler THEN
  646.           Write(bel);
  647.         END;
  648.       UNTIL NOT Fehler;
  649.       SetzePosition(X, Y);
  650.       WriteInt(Zahl, INTEGER(Laenge));
  651.     END ReadLongInt;
  652.   (*
  653.     --------------------------------------------------------------------
  654.     *)
  655.   PROCEDURE LoescheAusgabe();
  656.     (*
  657.       * LoescheAusgabe:
  658.       *  aktiven Bereich l”schen,
  659.       *  intern ber Screen.Scroll um Null Zeilen, BIOS Funktionsgruppe 16.
  660.     *)
  661.     BEGIN
  662.       Scroll(aBereich.B, 0);
  663.     END LoescheAusgabe;
  664.   PROCEDURE SetzePosition(X, Y : CARDINAL);
  665.     (*
  666.       * SetzePosition:
  667.       *  Cusorposition einstellen, Kontrolle erfolgt bei Write, WriteLn.
  668.     *)
  669.     BEGIN
  670.       Cursor.x := aBereich.B.left+INTEGER(X)-1;
  671.       Cursor.y := aBereich.B.top+INTEGER(Y)-1;
  672.       SetCursor(Cursor);
  673.     END SetzePosition;
  674.   PROCEDURE SetzeFarben(VFarbe, HFarbe : CARDINAL);
  675.     (*
  676.       * SetzeFarben:
  677.       *  Farben setzen ber Variable des Modules Screen,
  678.       *  intern BIOS Funktsionsgruppe 16.
  679.       *  BEACHTE Farbeeffekte fr Hintergrundfarben.
  680.     *)
  681.     BEGIN
  682.       Fore := VAL(Colors,VFarbe);
  683.       Back := VAL(Colors,HFarbe);
  684.     END SetzeFarben;
  685.   PROCEDURE NormaleAusgabe();
  686.     (*
  687.       * NormaleAusgabe:
  688.       *  Farben auf (Vordergrund, Hintergrund) einstellen.
  689.     *)
  690.     BEGIN
  691.       Fore := aBereich.VFarbe;
  692.       Back := aBereich.HFarbe;
  693.     END NormaleAusgabe;
  694.   PROCEDURE InverseAusgabe();
  695.     (*
  696.       * InverseAusgabe:
  697.       *  Farben auf (Hintergrund, Vordergrund) einstellen. 
  698.     *)
  699.     BEGIN
  700.       Fore := aBereich.HFarbe;
  701.       Back := aBereich.VFarbe;
  702.     END InverseAusgabe;
  703.   PROCEDURE CursorAn();
  704.     (*
  705.       * CursorAn:
  706.       *  Cursor ber BIOS Funktion (10, 100) einstellen,
  707.       *  ersteCursorZeile = 1, letzteCursorZeile = 7
  708.     *)
  709.     BEGIN
  710.       RegAX := 100H;
  711.       RegCX := 263;
  712.       SWI(10H);
  713.     END CursorAn;
  714.   PROCEDURE CursorAus();
  715.     (*
  716.       * CursorAus:
  717.       *  Cursor ber BIOS Funktion (10, 100) einstellen,
  718.       *  da Start- und Endzeile zum vollst„ndigen verschwinden des Cursors
  719.       *  nicht gefunden wurden wird ersteCursorZeile = 6, 
  720.       *  letzteCursorZeile = 7 definiert.
  721.       *  BEACHTE diese Werte sind spezifisch fr jeden PC-Kompatiblen,
  722.       *  gewisse Werte fhren zu interessanten Effekten in der 
  723.       *  Videodarstellung!
  724.     *)
  725.     BEGIN
  726.       RegAX := 100H;
  727.       RegCX := 1543;
  728.       SWI(10H);
  729.     END CursorAus;
  730.   PROCEDURE ZeileEinfuegen();
  731.     (*
  732.       * ZeileEinfuegen:
  733.       *  an der aktuellen Cursorposition wird eine Zeile eingefgt.
  734.       *  Mit Hilfe der Procedure Scroll wird ein Rechteck eum eine Zeile
  735.       *  nach unten gescrollt.
  736.     *)
  737.     VAR
  738.       Hilfe : Rectangle;
  739.     BEGIN
  740.       Hilfe := aBereich.B;
  741.       Hilfe.top := Cursor.y;
  742.       Scroll(Hilfe, -1);
  743.     END ZeileEinfuegen;
  744.   PROCEDURE ZeileLoeschen();
  745.     (*
  746.       * ZeileL”schen:
  747.       *  die Zeile, in der der Cursor ist wird gel”scht.
  748.       *  Mit Hilfe der Procedure Scroll wird ein  Rechteck um eine Zeile 
  749.       *  nach oben gescrollt.
  750.     *)
  751.     VAR
  752.       Hilfe : Rectangle;
  753.     BEGIN
  754.       Hilfe := aBereich.B;
  755.       Hilfe.top := Cursor.y;
  756.       Scroll(Hilfe, 1);
  757.     END ZeileLoeschen;
  758.   PROCEDURE ScrollHoch(n : CARDINAL);
  759.     (*
  760.       * ScrollHoch:
  761.       *  der aktuelle Bereich wird um n zeilen nach oben gescrollt,
  762.       *  n = 0 wird verhindert, da sonst der Bereich gel”scht wird.
  763.     *)
  764.     BEGIN
  765.       IF n#0 THEN
  766.         Scroll(aBereich.B, INTEGER(n));
  767.       END;
  768.     END ScrollHoch;
  769.   PROCEDURE ScrollRunter(n : CARDINAL);
  770.     (*
  771.       * ScrollRunter:
  772.       *  siehe auch ScrollHoch
  773.     *)
  774.     BEGIN
  775.       IF n#0 THEN
  776.         Scroll(aBereich.B, -INTEGER(n));
  777.       END;
  778.     END ScrollRunter;
  779.   (*
  780.     ----------------------------------------------------------------------
  781.     *)
  782.   PROCEDURE DefiniereBereich(VAR Bereich : TBereich; Links, Oben, 
  783.       Breite, Hoehe, VFarbe, HFarbe : CARDINAL);
  784.     (*
  785.       * DefiniereBereich:
  786.       *  dient zur Initialisierung des Bereiches
  787.     *)
  788.     BEGIN
  789.       WITH Bereich DO
  790.         B.left := INTEGER(Links)-1;
  791.         B.top := INTEGER(Oben)-1;
  792.         B.right := B.left+INTEGER(Breite);
  793.         B.bottom := B.top+INTEGER(Hoehe);
  794.       END;
  795.       Bereich.VFarbe := VAL(Colors,VFarbe);
  796.       Bereich.HFarbe := VAL(Colors,HFarbe);
  797.     END DefiniereBereich;
  798.   PROCEDURE BenutzeBereich(Bereich : TBereich);
  799.     (*
  800.       * BenutzeBereich:
  801.       *  nimmt einen vorher initialisierten Bereich als neuen aktuellen.
  802.     *)
  803.     BEGIN
  804.       aBereich := Bereich;
  805.       Fore := aBereich.VFarbe;
  806.       Back := aBereich.HFarbe;
  807.       SetzePosition(1, 1);
  808.     END BenutzeBereich;
  809.   PROCEDURE DefiniereZeile(VAR Zeile : TZeile; Wahl, Anzahl : CARDINAL; 
  810.       erlaubteZeichen : TZeichenMenge; P1, P2, P3, P4, P5, P6, P7, 
  811.       P8, P9, P10 : ARRAY OF CHAR);
  812.     (*
  813.       * DefiniereZeile:
  814.       *  Initialisiert die Datenstruktur, zu benutzen bei einer
  815.       *  ZeilenWahl
  816.     *)
  817.     BEGIN
  818.       Zeile.Wahl := Wahl;
  819.       Zeile.Anzahl := Anzahl;
  820.       Zeile.erlaubteZeichen := erlaubteZeichen;
  821.       WITH Zeile DO
  822.         Copy(Punkt[1], P1);
  823.         Copy(Punkt[2], P2);
  824.         Copy(Punkt[3], P3);
  825.         Copy(Punkt[4], P4);
  826.         Copy(Punkt[5], P5);
  827.         Copy(Punkt[6], P6);
  828.         Copy(Punkt[7], P7);
  829.         Copy(Punkt[8], P8);
  830.         Copy(Punkt[9], P9);
  831.         Copy(Punkt[10], P10);
  832.       END;
  833.     END DefiniereZeile;
  834.   PROCEDURE DefiniereMenue(VAR Menue : TMenue; Wahl, Anzahl, XTitel, 
  835.       YTitel, XPunkt, YPunkt : CARDINAL; Bereich : TBereich; Titel, 
  836.       P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 : ARRAY OF CHAR);
  837.     (*
  838.       * DefiniereMenue:
  839.       *  Initialisiert eine Datenstruktur, zu benutzen bei einer
  840.       *  MenueWahl.
  841.     *)
  842.     BEGIN
  843.       Menue.Wahl := Wahl;
  844.       Menue.Anzahl := Anzahl;
  845.       Menue.XTitel := XTitel;
  846.       Menue.YTitel := YTitel;
  847.       Menue.XPunkt := XPunkt;
  848.       Menue.YPunkt := YPunkt;
  849.       Menue.Bereich := Bereich;
  850.       Copy(Menue.Titel, Titel);
  851.       WITH Menue DO
  852.         Copy(Punkt[1], P1);
  853.         Copy(Punkt[2], P2);
  854.         Copy(Punkt[3], P3);
  855.         Copy(Punkt[4], P4);
  856.         Copy(Punkt[5], P5);
  857.         Copy(Punkt[6], P6);
  858.         Copy(Punkt[7], P7);
  859.         Copy(Punkt[8], P8);
  860.         Copy(Punkt[9], P9);
  861.         Copy(Punkt[10], P10);
  862.       END;
  863.     END DefiniereMenue;
  864.   (*
  865.     ----------------------------------------------------------------------
  866.     *)
  867.   PROCEDURE Meldung(Satz : ARRAY OF CHAR; Warte : BOOLEAN);
  868.     (*
  869.       * Meldung:
  870.       *  siehe auch Definitionsmodul.
  871.     *)
  872.     VAR
  873.       Zeichen : CHAR;
  874.     BEGIN
  875.       BenutzeBereich(Kommentar);
  876.       LoescheAusgabe();
  877.       SetzePosition(2, 2);
  878.       WriteString(Satz);
  879.       IF Warte THEN
  880.         CursorAn();
  881.         IF TasteGedrueckt() THEN
  882.           Read(Zeichen);
  883.         END;
  884.         Read(Zeichen);
  885.         CursorAus();
  886.       END;
  887.     END Meldung;
  888.   PROCEDURE MenueWahl(VAR Menue : TMenue; neuesMenue : BOOLEAN);
  889.     (*
  890.       * MenueWahl:
  891.       *  siehe auch Definitionsmodul.
  892.     *)
  893.     VAR
  894.       Zeichen : CHAR;
  895.       i : CARDINAL;
  896.     BEGIN
  897.       WITH Menue DO
  898.         BenutzeBereich(Kommentar);
  899.         LoescheAusgabe();
  900.         WriteString("W„hlen Sie mit den Pfeiltasten einen Punkt und");
  901.         WriteLn();
  902.         WriteString("aktivieren Sie den ausgew„hlten Punkt mit <RETURN>");
  903.         BenutzeBereich(Bereich);
  904.         IF neuesMenue THEN
  905.           LoescheAusgabe();
  906.           SetzePosition(XTitel, YTitel);
  907.           WriteString(Titel);
  908.           NormaleAusgabe();
  909.           FOR i := 1 TO Anzahl DO
  910.             SetzePosition(XPunkt, YPunkt-1+i);
  911.             WriteString(Punkt[i]);
  912.           END;
  913.         END;
  914.         REPEAT
  915.           InverseAusgabe();
  916.           SetzePosition(XPunkt, YPunkt-1+Wahl);
  917.           WriteString(Punkt[Wahl]);
  918.           NormaleAusgabe();
  919.           REPEAT
  920.             Read(Zeichen);
  921.           UNTIL ZeichenIstErlaubt(Zeichen,TZeichenMenge{Escape,Return,
  922.               Hoch,Runter},Status);
  923.           IF Status#Ende THEN
  924.             SetzePosition(XPunkt, YPunkt-1+Wahl);
  925.             WriteString(Punkt[Wahl]);
  926.           END;
  927.           IF SonderEingabe THEN
  928.             CASE Zeichen OF
  929.             | up, left :
  930.               IF Wahl=1 THEN
  931.                 Wahl := Anzahl;
  932.               ELSE
  933.                 DEC(Wahl);
  934.               END;
  935.             | down, right :
  936.               IF Wahl=Anzahl THEN
  937.                 Wahl := 1;
  938.               ELSE
  939.                 INC(Wahl);
  940.               END;
  941.             ELSE
  942.             END;
  943.           ELSE
  944.             CASE Zeichen OF
  945.             | esc :
  946.               Wahl := Anzahl;
  947.             ELSE
  948.             END;
  949.           END;
  950.         UNTIL NOT (SonderEingabe) AND (Zeichen=cr);
  951.         BenutzeBereich(Kommentar);
  952.         LoescheAusgabe();
  953.         BenutzeBereich(Bereich);
  954.       END;
  955.     END MenueWahl;
  956.   PROCEDURE ZeilenWahl(X, Y : CARDINAL; VAR Zeile : TZeile);
  957.     (*
  958.       * ZeilenWahl:
  959.       *  siehe auch Definitionsmodul.
  960.     *)
  961.     VAR
  962.       Zeichen : CHAR;
  963.     BEGIN
  964.       WITH Zeile DO
  965.         erlaubteZeichen := erlaubteZeichen+TZeichenMenge{Return};
  966.         Status := Normal;
  967.         REPEAT
  968.           InverseAusgabe();
  969.           SetzePosition(X, Y);
  970.           WriteString(Punkt[Wahl]);
  971.           SetzePosition(X, Y);
  972.           CursorAn();
  973.           REPEAT
  974.             Read(Zeichen);
  975.           UNTIL ZeichenIstErlaubt(Zeichen,erlaubteZeichen,Status);
  976.           CursorAus();
  977.           IF SonderEingabe THEN
  978.             CASE Zeichen OF
  979.             | left :
  980.               IF Wahl>1 THEN
  981.                 DEC(Wahl);
  982.               ELSE
  983.                 Wahl := Anzahl;
  984.               END;
  985.             | right :
  986.               IF Wahl<Anzahl THEN
  987.                 INC(Wahl);
  988.               ELSE
  989.                 Wahl := 1;
  990.               END;
  991.             ELSE
  992.             END;
  993.           ELSE
  994.             CASE Zeichen OF
  995.             | sp :
  996.               IF Wahl<Anzahl THEN
  997.                 INC(Wahl);
  998.               ELSE
  999.                 Wahl := 1;
  1000.               END;
  1001.             ELSE
  1002.             END;
  1003.           END;
  1004.         UNTIL Status#Normal;
  1005.         NormaleAusgabe();
  1006.         SetzePosition(X, Y);
  1007.         WriteString(Punkt[Wahl]);
  1008.       END;
  1009.     END ZeilenWahl;
  1010.   PROCEDURE ZeichenWahl(X, Y : CARDINAL; Satz : ARRAY OF CHAR; 
  1011.       erlaubteZeichen : TZeichenMenge; VAR Zeichen : CHAR);
  1012.     BEGIN
  1013.       SetzePosition(X, Y);
  1014.       WriteString(Satz);
  1015.       Write(" ");
  1016.       CursorAn();
  1017.       REPEAT
  1018.         Read(Zeichen);
  1019.       UNTIL ZeichenIstErlaubt(Zeichen,erlaubteZeichen,Status);
  1020.       IF NOT SonderEingabe AND (sp<=Zeichen) THEN
  1021.         Write(Zeichen);
  1022.       END;
  1023.       CursorAus();
  1024.     END ZeichenWahl;
  1025.   (*
  1026.     MODULE ConTools ---------------------------------------------------
  1027.     *)
  1028.   BEGIN
  1029.     (*
  1030.       * Initialisierung des Moduls:
  1031.       *  CursorAusschalten, Kommentarbereich definieren, aktuellen
  1032.       *  Bereich initialisieren, Bildschirm l”schen, Position (1,1) setzen.
  1033.     *)
  1034.     CursorAus();
  1035.     DefiniereBereich(Kommentar, 2, 21, 75, 3, 0, 1);
  1036.     DefiniereBereich(aBereich, 1, 1, 80, 24, 0, 3);
  1037.     BenutzeBereich(aBereich);
  1038.     SetzePosition(1, 1);
  1039.     LoescheAusgabe();
  1040.   END ConTools.
  1041.